                                                                                                                               package persistencia;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;

import entidades.Perfil;
import entidades.Usuario;

/**
 * Classe que contem os metodos de persistencia da Entidade Usuario.
 * 
 * @author Lino Bordin e Lucas Pessoa
 *
 */
public class UsuarioDAO {

	public final String ID = "idUsuario";
	public final String COLUNA_NOME = "nome";
	
	
	/**
	 * Sessao responsavel por realizar todas as transacoes com o o banco de
	 * dados utilizando o framework hibernate
	 */
	private SessionFactory factory;

	public SessionFactory getFactory() {
		return factory;
	}

	public void setFactory(SessionFactory factory) {
		this.factory = factory;
	}

	/**
	 * Metodo responsavel por implementar a operacao de insercao de um usuario.
	 * 
	 * @param Usuario a ser salvo no banco de dados
	 * @return void
	 */
	public void save(Usuario usuario) {
		
		Session session = factory.getCurrentSession();
		
		if (usuario != null) {
			
			session.save(usuario);

		}
		return;

	}
	
	/**
	 * Deleta o usuario com o id especificado
	 * 
	 * @param int ID unico do usuario
	 * @return void
	 */
	public void delete(int idUsr) {
		
		Session session = factory.getCurrentSession();
		Usuario usuario = new Usuario();

		Criteria criteria = session.createCriteria(Usuario.class);
		criteria.add(Restrictions.like(this.ID, idUsr));
		
		usuario = (Usuario) criteria.list().get(0);
		session.delete(usuario);

	}

	/**
	 * Atualiza dados de um usuario
	 * 
	 * @param Usuario com dados do usuario
	 * @return void
	 */
	public void update(Usuario usuario) {
		
		Session session = factory.getCurrentSession();
		
		if (usuario != null) {
			
			session.update(usuario);

		}
		return;

	}

	/**
	 * Lista em forma inclusiva todos os usuários que possuem um determinado conjunto de perfis
	 * 
	 * @param List<Perfil>
	 * @return List<Usuario>
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> listUsersInclusive(List<Perfil> listPerfil) {

		Session session = factory.getCurrentSession();
		Criteria criteria = session.createCriteria(Usuario.class);
		
		Conjunction conjunction = Restrictions.conjunction();//and
		
		if (listPerfil != null) {
			
			for (int i = 0; i < listPerfil.size(); i++) {
				
				conjunction.add(Restrictions.like(this.ID, listPerfil.get(i).getIdPerfil()));
				
			}
			
			criteria.add(conjunction);
			
		}

		List<Usuario> listaUsuarios = criteria.list();
		
		return  listaUsuarios;
		
	}
	
	/**
	 * Lista em forma exclusiva todos os usuários que possuem um determinado conjunto de perfis
	 * 
	 * @param List<Perfil>
	 * @return List<Usuario>
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> listUsersExclusive(List<Perfil> listPerfil) {

		Session session = factory.getCurrentSession();
		Criteria criteria = session.createCriteria(Usuario.class);
		
		Disjunction disjunction = Restrictions.disjunction();//or
		
		if (listPerfil != null) {
			
			for (int i = 0; i < listPerfil.size(); i++) {
				
				disjunction.add(Restrictions.like(this.ID, listPerfil.get(i).getIdPerfil()));
				
			}
			
			criteria.add(disjunction);
		}

		List<Usuario> listaUsuarios = criteria.list();
		
		return  listaUsuarios;
		
	}

	/**
	 * Lista todos os usuarios existentes no banco.
	 * 
	 * @return List<Usuario>
	 */
	@SuppressWarnings("unchecked")
	public List<Usuario> listaTodosUsuarios() {
		
		Session session = factory.getCurrentSession();
		Criteria criteria = session.createCriteria(Usuario.class);
		
		return criteria.list();
		
	}

	/**
	 * Encontra um determinado perfil
	 * 
	 * @param String perfil a ser encontrado
	 * @return Usuario
	 */
	public Usuario findUsuario(String usuario) {

		Session session = factory.getCurrentSession();
		Criteria criteria = session.createCriteria(Usuario.class);
		criteria.add(Restrictions.like(this.COLUNA_NOME, usuario));
		Usuario u = new Usuario();
		u = (Usuario) criteria.uniqueResult();
		return u;
		
	}


}
